﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Controllers
{
    public class FlowSet : BaseController
    {
        Dictionary<string, int> form2Flow = new Dictionary<string, int>();//默认签核流程为第一个
        Dictionary<string, string> form2Table = new Dictionary<string, string>();//表单对应的db表
        private IQueryable<SignConditions> list;
        private string signNodeIds;

        //构造函数
        public FlowSet()
        {
            form2Flow.Add("Form_Invi", 2);//招聘,对应人事签核流程

            form2Table.Add("Form_Vehi", "ReqVehicleMains");//用车申请
            form2Table.Add("Form_Evec", "ReqEvectionMains");//出差
            form2Table.Add("Form_Over", "ReqOvertime");//加班
            form2Table.Add("Form_Vaca", "ReqVacationMains");//请假
            form2Table.Add("Form_Perc", "ReqPerchaseMains");//采购
            //form2Table.Add("Form_Meet", "ReqMeetingRoom");//会议室 自动比对,已不用签核
            form2Table.Add("Form_Rece", "ReqReception");//商务接待

            form2Table.Add("Form_Week", "Weekly");//周报

            form2Table.Add("Form_Invi", "ReqInvite");//招聘
        }

        //设定签核流程
        public void SetSignFlow(string formNo, EmpBasicInfo ebi)
        {
            int flowId = form2Flow.SingleOrDefault(r => r.Key == formNo.Substring(0, 9)).Value;
            if (flowId == 0)
            {
                flowId = 1;
            }
            list = from r in ctx.SignConditions where r.FlowType == flowId orderby r.OrderNo, r.Id select r;
            signNodeIds = "";
            _getNextNodeId(formNo, null);
            //过滤经理签核或总监签核
            var minDeptId = ebi.EmpDepPos.OrderBy(r => r.DeptId).First().DeptId;//部门Id
            var minDept = ctx.Depts.Single(r => r.Id == minDeptId);//部门
            var minPosId = ebi.EmpDepPos.OrderBy(r => r.PosId).First().PosId;//职位

            #region 默认由行政部张绪盛经理(187)签核，如果申请天数少于两天则由杨俊明(314)签核
            int xingzhengCheckerId = 187;
            #region 请假
            if (formNo.IndexOf("Form_Vaca") >= 0)
            {
                ReqVacationMain req = ctx.ReqVacationMains.Single(q => q.FormNo == formNo);
                //主管级别或以下员工请假情况
                if (minPosId >=9)
                {
                    //请假小于等于两天 审批程序去除中心总监跟行政总监
                    if (req.DaysCnt <= 2)
                    {
                        signNodeIds = signNodeIds.Replace(",2", "").Replace(",4", "");
                        xingzhengCheckerId = 314;//杨明俊
                    }
                    //请假小于等于五天 审批程序去除行政总监    
                    else if (req.DaysCnt <= 5)
                    {
                        signNodeIds = signNodeIds.Replace(",4", "");
                    }
                }
                //经理助理级别以上员工
                else
                {
                    //请假小于等于两天 审批程序去除行政总监
                    if (req.DaysCnt <= 2)
                    {
                        signNodeIds = signNodeIds.Replace(",4", "");
                        xingzhengCheckerId = 314;//杨明俊
                    }
                }
            }
            #endregion
            #region 加班
            if (formNo.IndexOf("Form_Over") >= 0)
            {
                ReqOvertime req = ctx.ReqOvertimes.Single(q => q.FormNo == formNo);
                TimeSpan ts = req.PreEndTime - req.PreStartTime;
                if (minPosId>=9)
                {
                    if (ts.Days <= 2)
                    {
                        signNodeIds = signNodeIds.Replace(",2", "").Replace(",4", "");
                        xingzhengCheckerId = 314;//杨明俊
                    }
                    else if (ts.Days <= 5)
                        signNodeIds = signNodeIds.Replace(",4", "");
                }
                else
                {
                    if (ts.Days <= 2)
                    {
                        signNodeIds = signNodeIds.Replace(",4", "");
                        xingzhengCheckerId = 314;//杨明俊
                    }
                }
            }
            #endregion
            #endregion

            if (minPosId <= 7)
            {
                signNodeIds = signNodeIds.Replace(",1", "");//职位是副经理或以上,去除部门经理签核
                if (minPosId <= 4)
                {
                    signNodeIds = signNodeIds.Replace(",2", "");//职位是总监或以上,去除中心总监签核
                }
            }
            signNodeIds = signNodeIds.Trim(',');
            string[] ss = signNodeIds.Split(',');
            var signNodes = from r in ctx.SignNodes where ss.Contains(r.Id.ToString()) select r;//Contains必须是数组类型
            int order = 1;
            List<int> checkEmpIds = new List<int>();

            string strSql = @"with t as(select Id,Pid,[Text],OrderNo from Depts where Id={0} or (0={0} and Id=1)
                                  union all
                                  select a.Id,a.Pid,a.[Text],t.OrderNo+1 from Depts a,t where a.Id=t.Pid)
                                  select * from t order by OrderNo;";
            IEnumerable<Depts> depts = ctx.ExecuteQuery<Depts>(strSql, minDeptId.ToString()).ToList();

            #region 处理读出的每个节点
            foreach (string s in ss)
            {
                //周报只签核到总监
                if (s == "3" && formNo.Substring(0, 9) == "Form_Week") { break; }
                //财务中心主管以下员工周报只签核到经理,排除 唐细英(613)
                if (s == "2" && formNo.Substring(0, 9) == "Form_Week" && minPosId >= 10 && ebi.Id != 613 && (ebi.EmpDepPos.First().DeptId == 34 || ebi.EmpDepPos.First().DeptId == 35 || ebi.EmpDepPos.First().DeptId == 67)) { break; }
                //人事周报只签核到经理
                if (s == "2" && formNo.Substring(0, 9) == "Form_Week" && minDeptId== 9) { break; }

                SignNode sn = signNodes.Single(r => string.Equals(r.Id.ToString(), s));
                int currDeptId =0;
                if (sn.DepId == null)
                {
                    if (sn.PosIds == "4" || sn.PosIds == "5" || sn.PosIds == "4,5")//如果是总监或总监助理,则取中心id
                    {
                        currDeptId = depts.Single(r => r.Pid == 1).Id;
                    }
                    else if (sn.PosIds == "6" || sn.PosIds == "7" || sn.PosIds == "6,7")
                    {
                        currDeptId = minDeptId;
                    }
                }
                else
                {
                    currDeptId = (int)sn.DepId;
                }

                IQueryable<EmpDepPosition> iq = from r in ctx.EmpDepPositions
                                                where r.DeptId == currDeptId && sn.PosIds.Split(',').Contains(r.PosId.ToString())
                                                orderby r.PosId
                                                select r;
                EmpDepPosition edp = iq.FirstOrDefault();//可能找不到部门经理或中心总监

                #region 部门经理签核而没找到部门经理,分支和分仓
                if (s == "1" && edp == null)
                {
                    edp = new EmpDepPosition();
                    switch (minDeptId)//分支
                    {
                        case 26://浙江26
                            edp.EmpId = 311;//徐擎
                            break;
                        case 60://福建60
                            edp.EmpId =591;//费斌
                            break;
                        case 61://江西61
                            edp.EmpId =592;//祝词元
                            break;
                        case 27://辽宁27
                            edp.EmpId = 249;//徐东
                            break;
                        case 55://吉林55
                            edp.EmpId =557;//张文庆
                            break;
                        case 72://内蒙72
                            edp.EmpId = 676;//那娜
                            break;
                        case 64://黑龙江64
                            edp.EmpId =601;//张昕宇
                            break;
                        case 28://山东28
                            edp.EmpId =251;//程海涛
                            break;
                        case 54://河南54
                            edp.EmpId = 556;//崔常松
                            break;
                        case 63://河北63
                            edp.EmpId = 604;//郭海冲
                            break;
                        case 33://江苏33
                            edp.EmpId = 358;//李俊
                            break;
                        case 29://安徽29
                            edp.EmpId = 650;//张磊
                            break;
                        case 56://云南56
                            edp.EmpId = 561;//和平
                            break;
                        case 51://山西51
                            edp.EmpId = 548;//高云龙
                            break;
                        case 70://广西70
                            edp.EmpId = 337;//伍健文
                            break;
                        case 69://陕西69
                            edp.EmpId = 674;//魏铮
                            break;
                        case 62://湖北62
                            edp.EmpId = 597;//邱新
                            break;
                        case 48://四川48
                            edp.EmpId = 434;//徐成
                            break;
                    }
                    switch (minDeptId)//物流分仓
                    {
                        case 41:
                            edp.EmpId = 246;//沈阳分仓:徐超
                            break;
                        case 42:
                            edp.EmpId = 220;//郑州分仓:曹卫东
                            break;
                        case 40:
                            edp.EmpId = 268;//杭州分仓:周志军
                            break;
                    }
                }
                #endregion

                if (edp != null && edp.EmpId != 0 && !checkEmpIds.Contains(edp.EmpId)&&edp.EmpId!=ebi.Id)//不包含该签核节点,且签核节点不是自己
                {
                    //跳过杜总(165)签核的节点(经理助理及以下人员)
                    if (edp.EmpId == 165 && minPosId > 7) { continue; }
                    //跳过于阳(215)签核的节点
                    //if (edp.EmpId == 215) { continue; }

                    SignFlow sf = new SignFlow();
                    sf.FormNo = formNo;
                    //朱锦忠280周报签核(从符方214替换)去掉胡金球480杜淑贞643朱锦忠280胡少华635谢文财697徐嫒婷479
                    if (s == "1" && formNo.IndexOf("Form_Week") >= 0 && edp.EmpId == 214 && ebi.Id != 480 && ebi.Id != 643 && ebi.Id != 280 && ebi.Id != 635 && ebi.Id != 697 && ebi.Id != 479)
                    {
                        sf.CheckEmpId = 280;
                        sf.CheckNode = "助理签核";
                    }
                    else
                    {
                        sf.CheckEmpId = edp.EmpId;
                        sf.CheckNode = sn.NodeDesc;
                    }

                    //行政部的考勤签核
                    if (s == "3" && (formNo.Substring(0, 9) == "Form_Vaca" || formNo.Substring(0, 9) == "Form_Evec" || formNo.Substring(0, 9) == "Form_Over"))
                    {
                        if (!checkEmpIds.Contains(xingzhengCheckerId))
                        {
                            sf.FormNo = formNo;
                            sf.CheckEmpId = xingzhengCheckerId;
                            sf.Checker = "行政部";
                            sf.CheckNode = "行政部";
                        }
                    }

                    sf.IsCurrent = order == 1 ? 1 : 0;
                    sf.OrderNo = order++;
                    ctx.SignFlows.InsertOnSubmit(sf);
                    checkEmpIds.Add(edp.EmpId);
                }

                #region 分支机构插入区域经理
                if (s == "1" && (minDept.Pid == 24 || minDept.Pid == 27) && "Form_Vaca|Form_Week|Form_Evec".IndexOf(formNo.Substring(0, 9)) >= 0)
                {
                    int signId = _getAreaManager(minDeptId);
                    if (signId != 0 && !checkEmpIds.Contains(signId) && signId != ebi.Id)
                    {
                        SignFlow sf = new SignFlow();
                        sf.FormNo = formNo;
                        sf.CheckEmpId = signId;
                        sf.CheckNode = "区域经理";
                        sf.IsCurrent = order == 1 ? 1 : 0;
                        sf.OrderNo = order++;
                        ctx.SignFlows.InsertOnSubmit(sf);
                        checkEmpIds.Add(signId);
                    }
                }
                #endregion

                #region 分支管理部和市场部 子部门签核,较特殊
                if (s == "1")
                {
                    int signId = 0;
                    if (minDept.Pid == 24 || minDept.Pid == 27)//分支
                    {
                        if (formNo.IndexOf("Form_Evec_") >= 0)//出差
                        {
                            signId = 360;//贾哲龙
                            if (!checkEmpIds.Contains(signId))
                            {
                                SignFlow sf = new SignFlow();
                                sf.FormNo = formNo;
                                sf.CheckEmpId = signId;
                                sf.CheckNode = "公共事务部";
                                sf.IsCurrent = order == 1 ? 1 : 0;
                                sf.OrderNo = order++;
                                ctx.SignFlows.InsertOnSubmit(sf);
                                checkEmpIds.Add(signId);
                            }
                            signId = 219;//渠临峰
                            if (!checkEmpIds.Contains(signId))
                            {
                                SignFlow sf = new SignFlow();
                                sf.FormNo = formNo;
                                sf.CheckEmpId = signId;
                                sf.CheckNode = "机构管理部";
                                sf.IsCurrent = order == 1 ? 1 : 0;
                                sf.OrderNo = order++;
                                ctx.SignFlows.InsertOnSubmit(sf);
                                checkEmpIds.Add(signId);
                            }
                        }
                        else if ("Form_Vaca|Form_Invi|Form_Week".IndexOf(formNo.Substring(0, 9)) >= 0)//请假,招聘,周报
                        {
                            signId = 219;//渠临峰
                            if (!checkEmpIds.Contains(signId))
                            {
                                SignFlow sf = new SignFlow();
                                sf.FormNo = formNo;
                                sf.CheckEmpId = signId;
                                sf.CheckNode = "机构管理部";
                                sf.IsCurrent = order == 1 ? 1 : 0;
                                sf.OrderNo = order++;
                                ctx.SignFlows.InsertOnSubmit(sf);
                                checkEmpIds.Add(signId);
                            }
                            signId = 360;//贾哲龙
                            if (!checkEmpIds.Contains(signId))
                            {
                                SignFlow sf = new SignFlow();
                                sf.FormNo = formNo;
                                sf.CheckEmpId = signId;
                                sf.CheckNode = "公共事务部";
                                sf.IsCurrent = order == 1 ? 1 : 0;
                                sf.OrderNo = order++;
                                ctx.SignFlows.InsertOnSubmit(sf);
                                checkEmpIds.Add(signId);
                            }
                        }
                        else
                        {
                            signId = 219;//渠临峰
                            if (!checkEmpIds.Contains(signId))
                            {
                                SignFlow sf = new SignFlow();
                                sf.FormNo = formNo;
                                sf.CheckEmpId = signId;
                                sf.CheckNode = "机构管理部";
                                sf.IsCurrent = order == 1 ? 1 : 0;
                                sf.OrderNo = order++;
                                ctx.SignFlows.InsertOnSubmit(sf);
                                checkEmpIds.Add(signId);
                            }
                        }
                    }
                }
                if (s == "2" && ebi.Id != 229 && minDept.Pid == 12)//市场部二级部门签核
                {
                    int signId = 229;//张义林
                    if (!checkEmpIds.Contains(signId))
                    {
                        SignFlow sf = new SignFlow();
                        sf.FormNo = formNo;
                        sf.CheckEmpId = signId;
                        sf.CheckNode = "市场部签核";
                        sf.IsCurrent = order == 1 ? 1 : 0;
                        sf.OrderNo = order;
                        ctx.SignFlows.InsertOnSubmit(sf);
                        checkEmpIds.Add(signId);
                    }
                    signId = 239;//朱庆华
                    if (!checkEmpIds.Contains(signId))
                    {
                        SignFlow sf = new SignFlow();
                        sf.FormNo = formNo;
                        sf.CheckEmpId = signId;
                        sf.CheckNode = "市场部签核";
                        sf.IsCurrent = order == 1 ? 1 : 0;
                        sf.OrderNo = order++;
                        ctx.SignFlows.InsertOnSubmit(sf);
                        checkEmpIds.Add(signId);
                    }
                }
                #endregion

                #region 经理签核的节点上级部门的经理也进行签核
                int orderNo = depts.First().OrderNo + 1;
                Depts higherDept = depts.SingleOrDefault(r => r.OrderNo == orderNo);
                while (higherDept != null && higherDept.Pid != 1 && higherDept.Id != 1 && s == "1")
                {
                    IQueryable<EmpDepPosition> iq2 = from r in ctx.EmpDepPositions
                                                     where r.DeptId == higherDept.Id && sn.PosIds.Split(',').Contains(r.PosId.ToString())
                                                     orderby r.PosId
                                                     select r;
                    EmpDepPosition edp2 = iq2.FirstOrDefault();//可能找不到上级部门经理
                    if (edp2 != null && edp2.EmpId != 0 && !checkEmpIds.Contains(edp2.EmpId))//如果已包含该签核节点,则不添加
                    {
                        SignFlow sf = new SignFlow();
                        sf.FormNo = formNo;
                        sf.CheckEmpId = edp2.EmpId;
                        sf.CheckNode = "上级(副)经理";
                        sf.IsCurrent = order == 1 ? 1 : 0;
                        sf.OrderNo = order++;
                        ctx.SignFlows.InsertOnSubmit(sf);
                        checkEmpIds.Add(edp2.EmpId);
                    }
                    orderNo++;
                    higherDept = depts.SingleOrDefault(r => r.OrderNo == orderNo);
                }
                #endregion
            }
            #endregion
            #region 是否要签核到总经理
            bool isReqGenManager = false;
            if (formNo.IndexOf("Form_Vaca") >= 0)//请假
            {
                var v = ctx.ReqVacationMains.Single(r => r.FormNo == formNo);
                //主管级别以下员工 15天以上
                if (minPosId > 8 && v.DaysCnt > 15)
                {
                    isReqGenManager = true;
                }
                //经理助理级别以上员工  6天以上
                if (minPosId <= 8 && v.DaysCnt >= 6)
                {
                    isReqGenManager = true;
                }
            }
            else if (formNo.IndexOf("Form_Over") >= 0)//加班
            {
                var v = ctx.ReqOvertimes.Single(r => r.FormNo == formNo);
                DateTime dStart = v.PreStartTime;
                DateTime dEnd = v.PreEndTime;
                TimeSpan ts = dEnd - dStart;
                if (minPosId > 8 && ts.Days >= 15)
                {
                    isReqGenManager = true;
                }
                if (minPosId <= 8 && ts.Days >= 6)
                {
                    isReqGenManager = true;
                }
            }
            else if (formNo.IndexOf("Form_Evec") >= 0)//出差>5天
            {
                var scheduleList = ctx.ReqEvectionSchedules.Where(r => r.FormNo == formNo).ToList();
                DateTime sDate = scheduleList[0].PreStartTime;
                DateTime eDate = scheduleList[scheduleList.Count - 1].PreEndTime;
                if (eDate.Subtract(sDate).Days > 5)
                {
                    isReqGenManager = true;
                }
            }
            else if (formNo.IndexOf("Form_Perc") >= 0)//采购>1000元
            {
                var v = ctx.ReqPerchaseMains.Single(r => r.FormNo == formNo);
                if (v.Cost > 1000)
                {
                    isReqGenManager = true;
                }
            }
            if (isReqGenManager)
            {
                SignFlow sf = new SignFlow();
                sf.FormNo = formNo;
                sf.CheckEmpId = 160;
                sf.CheckNode = "总经理";
                sf.IsCurrent = order == 1 ? 1 : 0;
                sf.OrderNo = order++;
                ctx.SignFlows.InsertOnSubmit(sf);
            }
            #endregion

            ctx.SubmitChanges();
        }
        
        //获取顺序的签核节点id,递归调用
        private void _getNextNodeId(string formNo, int? nextNodeId)
        {
            IQueryable<SignConditions> list0;
            if (nextNodeId == null)
            {
                list0 = list.Where(r => r.FromNodeId.Equals(null));
            }
            else
            {
                list0 = list.Where(r => r.FromNodeId == nextNodeId);
            }
            foreach (SignConditions sc in list0)
            {
                if (sc.ToNodeId == null)
                {
                    break;
                }
                string condition = sc.Condition == null ? "" : " and " + sc.Condition;
                string tbName = form2Table.Single(r => r.Key == formNo.Substring(0, 9)).Value;
                string sqlStr = string.Format(@"select 0 from {0} a,EmpDepPositions b where a.EmpId=b.EmpId and a.FormNo='{1}'{2}", tbName, formNo, condition);
                IEnumerable<int> records = ctx.ExecuteQuery<int>(sqlStr);
                if (records.Count() > 0)
                {
                    signNodeIds += "," + sc.ToNodeId;
                    _getNextNodeId(formNo, sc.ToNodeId);
                    break;
                }
            }
        }

        //根据地区获取区域经理
        private int _getAreaManager(int deptid)
        {
            int empid = 0;
            switch (deptid)
            {
                //辽宁 吉林 黑龙江 内蒙古  
                case 27:
                case 55:
                case 64:
                case 72:
                    empid = 249;//徐东
                    break;
                //山东 河北 河南
                case 28:
                case 63:
                case 54:
                    empid = 251;//程海东
                    break;
                //浙江 江西 福建
                case 26:
                case 61:
                case 60:
                    empid = 311;//徐擎
                    break;
                //江苏 安徽
                case 33:
                case 29:
                    empid = 358;//李俊
                    break;
                //云南 贵州
                case 56:
                case 71:
                    empid = 561;//和平
                    break;
            }
            return empid;
        }
    }
}